

<template>
  <el-card shadow="hover">
    {{studentSearch}}
    <!--条件查询-->
    <el-form :inline="true" size="small" :model="studentSearch" class="demo-form-inline" align="left">
      <el-form-item >
        <el-input v-model="studentSearch.sname" placeholder="学生姓名"></el-input>
      </el-form-item>
      <el-form-item >
        <el-input v-model="studentSearch.addr" placeholder="学生住址"></el-input>
      </el-form-item>
      <el-form-item >
        <el-select v-model="studentSearch.cid" placeholder="所在班级">
          <el-option label="所有班级" value="0"></el-option>
          <el-option :label="c.cname" :value="c.cid" v-for="c in classes" :key="c.cid"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="search" icon="el-icon-search" plain>查询</el-button>
      </el-form-item>
      <el-form-item>
        <el-button type="danger" @click="handleDelete" icon="el-icon-remove" plain>批量删除</el-button>
      </el-form-item>
      <el-form-item>
        <el-button type="success" @click="addStudent" icon="el-icon-plus" plain>添加学生</el-button>
      </el-form-item>
    </el-form>
    <el-table
        :data="studentList"
        style="width: 100%"
        @selection-change="handleSelectionChange">
      <el-table-column
          type="selection"
          width="55">
      </el-table-column>
      <el-table-column
          label="学号"
          prop="sid"
          align="center" />
      <el-table-column
          label="学生姓名"
          prop="sname"
          align="center" />
      <el-table-column
          label="学生性别"
          prop="sex"
          align="center" />
      <el-table-column
          label="学生住址"
          prop="addr"
          align="center" />
      <el-table-column
          label="所在班级"
          prop="cname"
          align="center" />

      <el-table-column label="操作" align="center">
        <template slot-scope="scope">
          <el-button-group >
            <el-button type="primary" icon="el-icon-edit" size="mini" @click="handleEdit(scope.$index, scope.row)"></el-button>
            <el-button type="danger" icon="el-icon-delete"  size="mini" @click="handleDelete(scope.$index, scope.row)"></el-button>
          </el-button-group>
        </template>
      </el-table-column>
    </el-table>

    <!--分页导航-->
    <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="page"
        :page-sizes="[5, 10, 15, 20]"
        :page-size="pageSize"
        layout="total, sizes, prev, pager, next, jumper"
        :total="total">
    </el-pagination>

    <!--添加或修改学生的对话框-->
    <el-dialog :title="title" :visible.sync="dialogFormVisible"
               :close-on-click-modal="false" align="left">
      {{student}}
      <el-form :model="student" :rules="rules" ref="ruleForm" >
        <el-form-item label="学生姓名" :label-width="formLabelWidth" prop="sname">
          <el-input v-model="student.sname" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="学生性别" :label-width="formLabelWidth" prop="sex">
          <el-radio v-model="student.sex" label="男">男</el-radio>
          <el-radio v-model="student.sex" label="女">女</el-radio>
        </el-form-item>
        <el-form-item label="学生年龄" :label-width="formLabelWidth" prop="age">
          <el-input v-model.number="student.age" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="学生住址" :label-width="formLabelWidth" prop="addr">
          <el-input v-model="student.addr" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="所在班级" :label-width="formLabelWidth" prop="cid">
          <el-select v-model="student.cid" placeholder="请选择所在班级">
            <el-option label="所有班级" value="0"></el-option>
            <el-option :label="c.cname" :value="c.cid" v-for="c in classes" :key="c.cid"></el-option>
          </el-select>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="save">确 定</el-button>
      </div>
    </el-dialog>
  </el-card>
</template>

<script>
// 1. 引入访问后台的模块
import studentApi from '@/api/student'
import classesApi from '@/api/classes'
import student from "@/api/student";

export default {
  data() {
    // 自定义校验器
    let ageValidator = (rule,value,callback) => { // rule：验证规则 value: 输入的值 callback：回调
      if (!value){
        return callback(new Error("请输入年龄"))
      }else if (!Number.isInteger(value)){
        return callback(new Error("年龄必须是整数！"))
      }else if (value < 1 || value > 150){
        return callback(new Error("年龄不合法！"))
      }else{
        callback();
      }
    }
    return {
      studentList: [],        // 学生列表
      studentSearch:{},       // 当前查询的学生对象
      classes:[],             // 所有班级列表
      page:1,     // 当前页
      pageSize: 5,// 每页大小
      total: 100, // 总记录数
      title:'添加学生',   // 对话框标题
      dialogFormVisible:false, // 对话框是否可见
      formLabelWidth:'100px',  // 对话框前面的提示文本的宽度
      student:{},              // 编辑的是学生对象
      multipleSelection: [],   // 选中多个学生对象
      sids:[],                 // 代表要删除的学生编号
      // 定义表单验证规则的对象
      rules:{
        // 1. 验证用户名字段
        sname:[
          {required:true,message:'请输入用户名!',trigger:'blur'}
        ],
        // 2. 验证性别字段
        sex:[
          {required:true,message:'请选择性别！',trigger:'change'}
        ],
        // 3. 验证年龄字段
        age:[
          // {required:true,message:'请输入年龄!',trigger:'blur'}
          {validator: ageValidator,trigger:'blur'}
        ],
        // 4. 验证住址
        addr:[
          {required:true,message:'请输入住址！',trigger:'blur'}
        ],
        // 5. 验证班级名称字段
        cid:[
          {required:true,message:'请输入班级名称！',trigger:'blur'}
        ]
      }
    }
  },
  created() {
    // 1. 查询所有学生
    // this.findStudents()
    // 2. 分页查询学生
    // this.findByPage()
    this.search()
    // 3. 查询所有学生
    this.findClasses()
  },
  methods: {
    // 1. 查询所有学生
    async findStudents(){
      // 1.1 原生写法：
      // this.$axios.get("/student/list").then(({data}) => {
      //   console.log(data)
      //   this.studentList = data.data
      // })
      // 1.2 封装后的写法
      // studentApi.findStudents().then(({data}) => {
      //   this.studentList = data.data
      // })
      // 1.3 进一步封装为：
      const {data} = await studentApi.findStudents()
      this.studentList = data.data
    },
    // 2. 分页查询学生列表
    async findByPage(){
      // 2.1 原生写法：
      // this.$axios.get(`/student/findByPage/${this.page}/${this.pageSize}`).then(({data}) => {
      //   console.log(data)
      //   this.total = data.data.total
      //   this.studentList = data.data.rows
      // })
      // 2.2 封装后的写法
      // studentApi.findByPage(this.page,this.pageSize).then(({data}) => {
      //     console.log(data)
      //     this.total = data.data.total
      //     this.studentList = data.data.rows
      // })
      // 2.3 进一步改造为：
      const {data} = await studentApi.findByPage(this.page,this.pageSize)
      this.total = data.data.total
      this.studentList = data.data.rows

    },
    // 3. 查询所有班级
    async findClasses(){
      const {data} = await classesApi.findClasses()
      this.classes = data.data
    },
    // 4. 条件带分页查询
    async search(){
      const {data} = await studentApi.search(this.page,this.pageSize,this.studentSearch)
      this.total = data.data.total
      this.studentList = data.data.rows
    },
    // 5. 添加学生
    addStudent(){
      // 5.1 修改对话框的标题
      this.title = "添加学生"
      // 5.2 清空对话框中的数据
      this.student = {}
      // 5.3 打开对话框
      this.dialogFormVisible = true
    },
    // 7. 保存学生
     save(){
        // 参数valid如果为true,代表所有控件都验证通过，如果为false代表至少有一个控件未通过验证！
        this.$refs['ruleForm'].validate(async (valid) =>  {
          if (valid){   // 验证通过后，再进行添加或修改
           // 如何区分是添加还是修改操作？添加：学号sid没有值 修改：学号sid有值？
           let url = '/student/add'  // 添加
           let method = 'post'
           let _this = this       // 暂时保存this，后面会用到，后面因为有箭头函数，其this的作用域指向发生了改变
           if (this.student.sid){
             url = '/student/update'  // 修改
             method = 'put'
           }
           const {data} = await studentApi.save(url,this.student,method)
            console.log(data)
           if (data.code === 200){    // 代表后台请求处理成功
             this.$message({
               message: data.msg,
               type: 'success',
               onClose(){
                 _this.dialogFormVisible = false    // 关闭对话框
                 _this.search()                     // 重新刷新页面
               }
             });
           }
          }else{
            console.log("至少有一个表单控件未通过验证！")
            return false
          }
        })
    },
    // 8. 修改学生
    handleEdit(index, row) {
      console.log(index, row);
      // 8.1 为student对象赋值
      this.student = row
      // 8.2 修改对话框标题
      this.title = "修改学生"
      // 8.3 打开对话框
      this.dialogFormVisible = true
    },
    // 删除学生
    // 如何区分删除单个学生还是多个学生？
    // 可以查看row是否是undefined，如果是证明是批量删除，否则，是删除单个学生？
    // 删除传递给后台的是一个sid的数组，可以是一个值（单个删除），也可以多个值（批量删除）
    handleDelete(index, row) {
      // 第一步：处理要删除的sid学生编号数组
      if (row){   // 证明删除的是单个学生
        this.sids = [row.sid]
      }else{      // 证明删除的是多个学生（批量删除）
        this.sids = this.multipleSelection.map(st => st.sid)
      }
      // 第二步：向后台发送请求
      this.$confirm(`此操作将永久删除学号为${this.sids}的学生, 是否继续?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then( async () => {         // 代表点了‘确定’按钮后完成的事情，此时向后台发送请求，开始执行真正的删除操作！
        const {data} = await studentApi.delStudent(this.sids)
        const _this = this
        if (data.code === 200){
          this.$message({
            type: 'success',
            message: data.msg,
            onClose(){            // 消息提示框关闭时，刷新页面
              _this.search()      // 刷新页面
            }
          });
        }
      }).catch(() => {      // 代表点了取消按钮后完成的事情
        this.$message({
          type: 'info',
          message: '已取消删除'
        });
      });
    },
    // 页大小pageSize改变时触发
    handleSizeChange(val) {
      this.pageSize = val
      // this.findByPage()
      this.search()
      console.log(`每页 ${val} 条`);
    },
    // 当前页page发生改变时触发
    handleCurrentChange(val) {
      this.page = val
      // this.findByPage()
      this.search()
      console.log(`当前页: ${val}`);
    },
    handleSelectionChange(val) {
      this.multipleSelection = val;
      console.log(this.multipleSelection)
    },
  }
}
</script>

<style>
.el-pagination{
  margin-top: 20px;
  text-align: right;
}
</style>
